package com.pai4j.pgc.service.resource.convert;
import com.pai4j.common.enums.community.ResourceFormatEnum;
import com.pai4j.common.service.FileUploadService;
import com.pai4j.common.util.*;
import com.pai4j.domain.community.vo.response.resource.ResourceConvertBufferImageResult;
import com.pai4j.domain.community.vo.response.resource.ResourceConvertImageResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.pai4j.common.util.DateUtils.YYYYMMDD;

/**
 *
 *
 * @author: CYM-pai
 * @date: 2025/10/27 17:31
 **/
@Slf4j
public abstract class AbstractResourceConvertImageService implements IResourceConvertImage {

    /***
     * 默认转换图片格式
     */
    public static final String DEFAULT_IMG_EXT = "jpg";
    public static final String DEFAULT_IMG_EXT_NAME = ".jpg";

    /***
     * 216为图片像素点dpi
     */
    public static final int DEFAULT_IMAGE_DPI = 216;
    /***
     * 最大支持10M
     */
    private static final int MAX_SUPPORT_FILE_SIZE = 100 * 1024 * 1000;
    /***
     * 本地临时文件目录
     */
//    public static final String LOCAL_TEMP_DIR = "/Users/wangqi49/Desktop/resource/";
    public static final String LOCAL_TEMP_DIR = "/home/work/temp/resource/";
    /***
     * 资源
     */
    public File file;

    public String extName;

    /***
     * 最大支持转换100张图片
     */
    public int maxImageCount = 15;

    /***
     * 真正执行文件转换为图片的抽象方法
     * @return
     */
    abstract ResourceConvertBufferImageResult doProcess();

    public void beforeProcess(String netWorkResourceUrl) {
        // 下载网络资源
        this.extName = extName(netWorkResourceUrl);
        this.file = downloadNetWorkFile(netWorkResourceUrl);
        Assert.isTrue(file != null && file.length() > 0, "资源转图片失败：未获取到资源");
    }

    @Override
    public ResourceConvertImageResult convert(String netWorkResourceUrl, int maxSize) {
        this.maxImageCount = maxSize > maxImageCount ? maxImageCount : maxSize;
        // 下载网络资源
        beforeProcess(netWorkResourceUrl);
        // 转图片
        ResourceConvertBufferImageResult resourceConvertBufferImageResult = this.doProcess();
        Assert.isTrue(resourceConvertBufferImageResult != null &&
                CollectionUtils.isNotEmpty(resourceConvertBufferImageResult.getBufferedImages()), "资源转图片失败");
        List<String> images = this.batchUploadBufferImage2OSS(resourceConvertBufferImageResult.getBufferedImages());
        return new ResourceConvertImageResult(resourceConvertBufferImageResult.getPageCount(), images);
    }

    @Override
    public String format(String netWorkResourceUrl) {
        return ResourceFormatEnum.getFileExtNameByFileName(netWorkResourceUrl);
    }

    @Override
    public String extName(String netWorkResourceUrl) {
        return ResourceFormatEnum.getFileExtNameByFileName(netWorkResourceUrl);
    }

    @Override
    public File downloadNetWorkFile(String netWorkResourceUrl) {
        // 临时下载目录 TEMP_DIR + 今天
        String tempDownloadDir = LOCAL_TEMP_DIR.concat(DateUtils.getDate2String(YYYYMMDD, new Date())).concat("/");
        File dirWithDate = new File(tempDownloadDir);
        if (!dirWithDate.exists()) {
            // 目录不存在时，创建临时目录
            dirWithDate.mkdirs();
        }
        // 文件名称规则
        String format = this.format(netWorkResourceUrl);
        String fileName = tempDownloadDir.concat(FileUtil.generateFileName(System.currentTimeMillis() + "." +format));
        // 下载文件
        File downloadFile = new File(fileName);
        // 下载到本地
        HttpClientUtil.downloadByResourceUrl(netWorkResourceUrl, null, null, downloadFile);
        return downloadFile;
    }

    /***
     * 批量上传图片到OSS
     * @param bufferedImageList
     * @return
     */
    private List<String> batchUploadBufferImage2OSS(List<BufferedImage> bufferedImageList) {
        List<String> netWorkImageUrlList = new ArrayList<>();
        bufferedImageList.stream().forEach(img -> netWorkImageUrlList.add(this.uploadBufferImage2OSS(img)));
        return netWorkImageUrlList.stream()
                .filter(imgUrl -> StringUtils.isNotBlank(imgUrl))
                .collect(Collectors.toList());
    }

    /***
     * 上传图片到OSS
     * @param bufferedImage
     * @return
     */
    private String uploadBufferImage2OSS(BufferedImage bufferedImage) {
        String ossFileName = generateImageName();
        FileUploadService fileUploadService = SpringContextUtil.getBean(FileUploadService.class);
        try {
            return fileUploadService.uploadAndGetUrl("RES_IMG", ossFileName,
                    FileConvertUtil.convertBufferedImageToMultipartFile(bufferedImage).getInputStream());
        } catch (IOException e) {
            log.error("上传转换后的图片到OSS失败.", e);
        }
        return null;
    }

    /***
     * 随机生成图片名称，基于UUID
     * @return
     */
    public String generateImageName() {
        String ossFileName = IDGenerateUtil.createId("CU_RES_IMG");
        ossFileName = ossFileName.concat(DEFAULT_IMG_EXT_NAME);
        return ossFileName;
    }
}
